/****************************************************************
 ** Product  :   HP Subscriber Network Application Policy
 ** Module   :   gr-manager
 ** Date: Apr 10, 2015               
 ** Author: hua zhen
 ** (C) Copyright 2015, Hewlett-Packard Company, All Rights Reserved.
 ** This software is the proprietary information of HP, Inc.  
 ** Use is subject to license terms.
 *****************************************************************
 ** Description:   
 **   Get VoltDB database information and promote VoltDB database through by call VoltDB system store procedure.
 **  
 ****************************************************************/
package com.hp.snap.gr.utils;

import com.google.gson.Gson;
import com.hp.snap.gr.db.voltdb.ControlDRAgent;
import com.hp.snap.gr.db.voltdb.JSONHttpVoltDBClientFactory;
import com.hp.snap.gr.db.voltdb.VoltDBClientConfig;
import com.hp.snap.gr.db.voltdb.sp.CommandResponses;
import com.hp.snap.gr.exception.ActionException;
import com.hp.snap.gr.exception.DatabaseException;
import com.hp.snap.gr.model.DBSystemInfo;
import com.hp.snap.gr.model.Database;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * Get VoltDB database information and promote VoltDB database through by call VoltDB system store procedure.
 *
 * <P>
 * Version: 3.3 <br>
 * Author: hua zhen
 * Date: Apr 10, 2015
 * 
 * </P>
 *
 **/
public class VoltDBStoreProcedureController {
    private static Logger logger = LoggerFactory.getLogger(VoltDBStoreProcedureController.class);

//    public static void pauseDatabase(Database database, String siteName) throws ActionException {
//        validateParams(database);
//        JSONObject res = callStoreProcdure(ControlDRAgent.getVoltDBClientConfig(database, siteName), Constants.STORED_PROCEDURE_PAUSE);
//        String errString = null;
//        if (!CommandResponses.isExecuteSuccess(res, errString)) {
//            logger.warn("Pausing VoltDB [{}] faild for {}", database.getName(), errString);
//        }
//    }
//
//    public static void stopDatabase(Database database, String siteName) throws ActionException {
//        validateParams(database);
//        JSONObject res = callStoreProcdure(ControlDRAgent.getVoltDBClientConfig(database, siteName), Constants.STORED_PROCEDURE_SHUTDOWN);
//        String errString = null;
//        if (!CommandResponses.isExecuteSuccess(res, errString)) {
//            logger.warn("Stopping VoltDB [{}] faild for {}", database.getName(), errString);
//        }
//    }
//
//    public static void resumeDatabase(Database database, String siteName) throws ActionException {
//        validateParams(database);
//        JSONObject res = callStoreProcdure(ControlDRAgent.getVoltDBClientConfig(database, siteName), Constants.STORED_PROCEDURE_RESUME);
//        String errString = null;
//        if (!CommandResponses.isExecuteSuccess(res, errString)) {
//            logger.warn("Resuming VoltDB [{}] faild for {}", database.getName(), errString);
//        }
//    }

    public static void promoteDatabase(Database database, String siteName) throws ActionException {
        validateParams(database);
        JSONObject response = callStoreProcdure(ControlDRAgent.getVoltDBClientConfig(database, siteName), Constants.STORED_PROCEDURE_PROMOTE);
        String errString;
        try {
            int status = response.getInt("status");
            if (status < 0) {
                errString = response.getString("statusstring");
                throw new ActionException("Promoting VoltDB [" + database.getName() + "] failed: " + errString);
            }
        } catch (JSONException e) {
            throw new ActionException("Promoting VoltDB [" + database.getName() + "] failed: " + e.getMessage(), e);
        }
    }

    public static DBSystemInfo getDatabaseSystemInfo(Database database, String siteName) throws ActionException {
        validateParams(database);
        JSONObject res = callStoreProcdure(ControlDRAgent.getVoltDBClientConfig(database, siteName), Constants.STORED_PROCEDURE_SYSTEMINFORMATION);
        return CommandResponses.getDBSystemInformation(res);
    }

    public static boolean isReplica(Database database, String siteName) throws ActionException {
        DBSystemInfo dbSysInfo = getDatabaseSystemInfo(database, siteName);
        return dbSysInfo != null && dbSysInfo.getReplicationrole().equalsIgnoreCase(Constants.REPLICA_STATUS_ON);

    }

    private static JSONObject callStoreProcdure(List<VoltDBClientConfig> configs, String scName) throws DatabaseException {
        JSONObject response = null;
        for (VoltDBClientConfig config : configs) {
            if (config != null) {
                config.setAdmin(true);
            }
        }
        JSONHttpVoltDBClientFactory factory = new JSONHttpVoltDBClientFactory(configs);
        response = factory.invokeStoredProcedure(scName, null);
        if (logger.isDebugEnabled()) {
            logger.debug("[callStoreProcdure] get response={}", new Gson().toJson(response, JSONObject.class));
        }
        return response;
    }

    private static void validateParams(Database database) throws DatabaseException {
        if (database == null || database.getServers() == null || database.getServers().isEmpty()) {
            throw new DatabaseException("input invalid parameter: database={}" + new Gson().toJson(database, Database.class));
        }
    }
}
